import type { Lines } from 'lrc-file-parser'
import Lyric from 'lrc-file-parser'
import { getSongLyric } from '@/api/common'
import { usePlayerStore } from '@/stores/playerStore'
import type { Ref, UnwrapRef } from 'vue'
import Scroll from '@/components/scroll/index.vue'
interface FunReturnType {
  currentLyric: Ref<UnwrapRef<Lyric | undefined>>
  currentLineText: Ref<string>
  currentLineNum: Ref<number>
  playLyric: (time: number) => void
  pauseLyric: () => void
  isTouchMove: Ref<boolean>
  showTimeLine: Ref<boolean>
  currentScrollLyricIndex: Ref<number>
  touchstart: () => void
  touchmove: () => void
  touchend: (event: TouchEvent) => void
  scrollHandle: (pos: IPos) => void
}
export default function useLyric(
  showCdWrapper: Ref<boolean>,
  lyricContainerRef: Ref<HTMLUListElement | null>,
  lyricScrollRef: Ref<InstanceType<typeof Scroll> | null>,
  canPlay: Ref<boolean>,
  currentTime: Ref<number>
): FunReturnType {
  const playerStore = usePlayerStore()
  // 歌词对象
  const currentLyric = ref<Lyric>()
  // 当前歌词播放行
  const currentLineText = ref<string>('')
  // 当前歌词行对应的索引
  const currentLineNum = ref<number>(0)
  const isTouchMove = ref<boolean>(false)
  const showTimeLine = ref<boolean>(false)
  const lyricHeights = ref<number[]>([])
  const currentScrollLyricIndex = ref<number>(0)
  watch(
    () => playerStore.currentSong,
    async (newSong: ISongItem | undefined, prevSong: ISongItem | undefined) => {
      if (newSong && prevSong && newSong.id === prevSong.id) {
        return
      }
      pauseLyric()
      clearTimeout(timer)
      clearTimeout(innerTimer)
      isTouchMove.value = false
      currentLyric.value = undefined
      currentLineText.value = ''
      currentLineNum.value = 0
      if (newSong && newSong.lyricInstance instanceof Lyric) {
        newSong.lyricInstance.setLyric(newSong.lyricInstance.lyric)
        currentLyric.value = newSong.lyricInstance
      } else {
        if (!newSong) {
          return
        }
        const {
          lrc: { lyric }
        } = await getSongLyric(newSong.id)
        const lrc = (currentLyric.value = new Lyric({
          async onPlay(line: number, text: string) {
            currentLineNum.value = line
            currentLineText.value = text
            // Listening play event
            // console.log(line, text) // line is line number of current play
            // text is lyric text of current play line
            await nextTick()
            const eles = document.querySelectorAll('.lyric-wrapper .lyric-item')
            if (!isTouchMove.value) {
              const lineEl = eles[line]
              lineEl && lyricScrollRef.value?.scrollToElement(lineEl as HTMLElement)
            }
          },
          onSetLyric(lines: Lines) {
            // listening lyrics seting event
            // console.log(lines) // lines is array of all lyric text
            if (canPlay.value) {
              currentLyric.value?.play(0)
            }
          },
          offset: 0, // offset time(ms), default is 150 ms
          playbackRate: 1, // playback rate, default is 1
          isRemoveBlankLine: true // is remove blank line, default is true
        }))
        if (newSong) {
          newSong.lyricInstance = lrc
        }
        lrc.setLyric(lyric)
      }
    }
  )
  watch(showCdWrapper, async (newVal) => {
    if (newVal) {
      return
    }
    await nextTick()
    let height = 0
    const lyricContainerRefVal = lyricContainerRef.value
    const length = lyricContainerRefVal?.children.length || 0
    const lyricHeightsVal = lyricHeights.value
    lyricHeightsVal.length = 0
    lyricHeightsVal.push(height)
    for (let i = 0; i < length; i++) {
      height += lyricContainerRefVal!.children[i].clientHeight
      lyricHeightsVal.push(height)
    }
  })
  watch(
    () => playerStore.fullScreen,
    async (newVal: boolean) => {
      await nextTick()
      if (newVal) {
        const eles = document.querySelectorAll('.lyric-wrapper .lyric-item')
        const line = currentLineNum.value
        const lineEl = eles[line]
        lineEl && lyricScrollRef.value?.scrollToElement(lineEl as HTMLElement)
      }
    }
  )
  watch(
    () => playerStore.playing,
    (newPlaying) => {
      if (!newPlaying) {
        // 暂停歌词播放
        pauseLyric()
      }
    }
  )
  function playLyric(time: number) {
    currentLyric.value?.play(time)
  }
  function pauseLyric() {
    currentLyric.value?.pause()
  }
  let timer: number | undefined
  let innerTimer: number | undefined
  function touchstart() {
    clearTimeout(timer)
    clearTimeout(innerTimer)
    isTouchMove.value = false
  }
  function touchmove() {
    isTouchMove.value = true
    showTimeLine.value = true
  }
  function touchend() {
    const eles = document.querySelectorAll('.lyric-wrapper .lyric-item')
    clearTimeout(timer)
    clearTimeout(innerTimer)
    timer = setTimeout(() => {
      const line = currentLineNum.value
      const lineEl = eles[line]
      lineEl && lyricScrollRef.value?.scrollToElement(lineEl as HTMLElement)
      isTouchMove.value = false
      innerTimer = setTimeout(() => {
        showTimeLine.value = false
      }, 2000)
    }, 2000)
  }
  function scrollHandle(pos: IPos) {
    if (!isTouchMove.value) {
      return
    }
    const scrollY = -pos.y
    for (let i = 0; i < lyricHeights.value.length - 1; i++) {
      const prevHeight = lyricHeights.value[i]
      const nextHeight = lyricHeights.value[i + 1]
      if (scrollY >= prevHeight && scrollY <= nextHeight) {
        currentScrollLyricIndex.value = i
      }
    }
  }
  return {
    currentLyric,
    currentLineText,
    currentLineNum,
    isTouchMove,
    showTimeLine,
    currentScrollLyricIndex,
    playLyric,
    pauseLyric,
    touchstart,
    touchmove,
    touchend,
    scrollHandle
  }
}
